/**
 * request 
 * @Class Request
 * @description http请求插件
 * @Author dinghao
 * @Date 2024-01-01
 * VUE 2.0
 */

import sysConfig from '@/common/config/config.js'

export default class Request {
	//http请求需要的配置信息
	config = {
		baseUrl: '',
		header: {
			'content-type': 'application/json',
		},
		method: '',
		dataType: 'json',
		timeout: 30000,
	}

	/**
	 * 拦截器
	 * @property {Function} request 请求拦截器
	 * @property {Function} response 响应拦截器
	 * @type {{request: Request.interceptor.request, response: Request.interceptor.response}}
	 */
	interceptor = {
		request: (cb) => {
			if (cb) {
				this.requestBeforeFun = cb
			}
		},

		response: (cb) => {
			if (cb) {
				this.requestComFun = cb
			}
		}

	}

	requestBeforeFun = (config) => {
		return config
	}

	requestComFun = (response) => {
		return response
	}

	/**
	 * 自定义验证器，如果返回true 则进入响应拦截器的响应成功函数(resolve)，否则进入响应拦截器的响应错误函数(reject)
	 * @param { Number } statusCode - 请求响应体statusCode（只读）
	 * @return { Boolean } 如果为true,则 resolve, 否则 reject
	 */
	validateStatus(statusCode) {
		return statusCode === 200
	}

	/**
	 * @Function
	 * @param {Request~setConfigCallback} f - 设置全局默认配置
	 */
	setConfig(f) {
		this.config = f(this.config)
	}

	/**
	 * @Function
	 * @param {Object} options - 请求配置项
	 * @prop {String} options.url - 请求路径
	 * @prop {Object} options.data - 请求参数
	 * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
	 * @prop {Object} [options.dataType = config.dataType] - 如果设为 json，会尝试对返回的数据做一次 JSON.parse
	 * @prop {Object} [options.header = config.header] - 请求header
	 * @prop {Object} [options.method = config.method] - 请求方法
	 * @returns {Promise<unknown>}
	 */

	async request(options = {}) {
		//设置请求参数
		var apiUrl = this.config.baseUrl + options.url;
		var apiParams = options.params || {}
		const apiData = options.data || {};
		const apiMethod = options.method;
		const apiDataType = this.config.dataType;
		const head = options.headers || {};
		const handleRe = {
			...this.requestBeforeFun(options)
		};
		// if(handleRe.header.Authorization==''){
		// 	handleRe.header.Authorization=uni.getStorageSync('token');
		// }
		this.config.header = {
			...this.config.header,
			...head,
			'Clientid': handleRe.header.Clientid,
			'Authorization': 'Bearer ' + handleRe.header.Authorization
		}
		const apiHeader = this.config.header;
		//发起同步请求
		return new Promise((resolve, reject) => {
			uni.request({
				url: apiUrl + this.tansParams(apiParams),
				data: apiData,
				method: apiMethod,
				header: apiHeader,
				dataType: apiDataType,
				complete: (response) => {
					response.config = handleRe
					if (this.validateStatus(response.statusCode)) { // 成功
						response = this.requestComFun(response)
						resolve(response)
					} else {
						reject(response)
					}
				}
			})
		})
	}

	tansParams(params) {
		let result = ''
		for (const propName of Object.keys(params)) {
		  const value = params[propName]
		  var part = encodeURIComponent(propName) + "="
		  if (value !== null && value !== "" && typeof (value) !== "undefined") {
		    if (typeof value === 'object') {
		      for (const key of Object.keys(value)) {
		        if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
		          let params = propName + '[' + key + ']'
		          var subPart = encodeURIComponent(params) + "="
		          result += subPart + encodeURIComponent(value[key]) + "&"
		        }
		      }
		    } else {
		      result += part + encodeURIComponent(value) + "&"
		    }
		  }
		}
		return result
	}

	get(url, options = {}) {
		return this.request({
			url,
			method: 'GET',
			...options
		})
	}

	post(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'POST',
			...options
		})
	}
	
	delete(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'DELETE',
			...options
		})
	}

	upload(url,params) {
		let data = '';
		uni.showLoading({
			title:'加载中',
			icon: 'none'
		})
		let paramData = params.formData;
		return new Promise((resolve, reject) => {
			uni.uploadFile({
				url: sysConfig.congifService.apiUrl + url, // 后端接口地址
				filePath: params.file,
				name: 'file', // 后端接收文件的参数名，需与后端接口中的参数名保持一致
				formData: paramData,
				header: {
					'Authorization': uni.getStorageSync('token'),
					'Clientid':sysConfig.congifService.client
				},
				success: (uploadRes) => {
					uni.hideLoading();
					resolve(uploadRes);
				},
				fail: (uploadErr) => {
					uni.hideLoading();
					uni.showToast({
						title: '上传失败',
						icon: 'none',
						duration: 2000
					});
					reject(uploadErr); // 返回上传失败的错误信息
				}
			});
		});
	}

}